package com.ucode.springboot.starter.ESsearch.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import com.ucode.springboot.starter.ESsearch.annotation.ESField;
import com.ucode.springboot.starter.ESsearch.annotation.ESDocument;
import com.ucode.springboot.starter.ESsearch.annotation.metadata.ESDocumentData;
import com.ucode.springboot.starter.ESsearch.annotation.metadata.EsFieldData;
import cn.hutool.core.util.StrUtil;

public class EsTools {
    
//    /**
//     * 根据对象中的注解获取ID的字段值
//     * @param obj
//     * @return
//     */
//    public static String getDocEsId(Object obj) throws Exception {
//        Field[] fields = obj.getClass().getDeclaredFields();
//        for(Field f : fields){
//            f.setAccessible(true);
//            ESID esid = f.getAnnotation(ESID.class);
//            if(esid != null){
//                Object value = f.get(obj);
//                if(value == null){
//                    return null;
//                }else{
//                    return value.toString();
//                }
//            }
//        }
//        return null;
//    }

    /**
     * 获取DocEsIndex注解元数据
     * @author liliang
     * @date 2019年12月30日
     * @param clazz
     * @return
     */
    public static ESDocumentData getDocEsIndexMetadata(Class<?> clazz){
        //为了提升效率,可以做缓存
        
        ESDocumentData metaData = null;
        if(clazz != null){
            ESDocument docEsIndex = clazz.getAnnotation(ESDocument.class);
            if(docEsIndex != null){
                String indexname = docEsIndex.indexName();
                String idFieldName = docEsIndex.idFieldName();
                int number_of_shards = docEsIndex.numberOfShards();
                int number_of_replicas = docEsIndex.numberOfReplicas();
                metaData = new ESDocumentData(indexname, idFieldName, number_of_shards, number_of_replicas);
            }
        }
        return metaData;
    }
    
    public static String getId(Object obj,String idFieldName){
        Object id = null;
        if(obj != null && StrUtil.isNotBlank(idFieldName)){
            String idGetMethod = "get"+idFieldName.substring(0,1).toUpperCase()+idFieldName.substring(1);
            try {
                Method method= obj.getClass().getMethod(idGetMethod);
                id = method.invoke(obj);
            } catch (Exception e) {
                
            }
        }
        return id != null ?id.toString() : null;
    }
    
    
    public static EsFieldData getDocEsMappingMetadata(Field field){
        EsFieldData mappingData = null;
        if(field != null){
            field.setAccessible(true);//反射时访问私有变量
            
            mappingData = new EsFieldData();
            mappingData.setFieldName(field.getName());
            ESField esMapping = field.getAnnotation(ESField.class);
            if(esMapping != null){
                mappingData.setDatatype(esMapping.datatype().toString().replaceAll("_type",""));
                mappingData.setAnalyzer(esMapping.analyzer().toString());
                mappingData.setNgram(esMapping.ngram());
                mappingData.setIgnoreAbove(esMapping.ignoreAbove());
                mappingData.setSearchAnalyzer(esMapping.searchAnalyzer().toString());
                mappingData.setKeyword(esMapping.keyword());
                mappingData.setSuggest(esMapping.suggest());
                mappingData.setAllowSearch(esMapping.allowSearch());
                mappingData.setCopyTo(esMapping.copyTo());
                mappingData.setNestedClass(esMapping.nestedClass());
                if(StrUtil.isNotBlank(esMapping.nullValue())){
                    mappingData.setNullValue(esMapping.nullValue());
                }
            }else{
                mappingData.setDatatype("text");
                mappingData.setAnalyzer("standard");
                mappingData.setNgram(false);
                mappingData.setIgnoreAbove(256);
                mappingData.setSearchAnalyzer("standard");
                mappingData.setKeyword(true);
                mappingData.setSuggest(false);
                mappingData.setAllowSearch(true);
                mappingData.setCopyTo("");
                mappingData.setNestedClass(null);
          }
        }
        return mappingData;
    }
    
    public static EsFieldData[] getDocEsMappingMetadatas(Class<?> clazz){
        Field[] fields = clazz.getDeclaredFields();
        int length = 0;
        EsFieldData[] mappingMetadatas = null;
        if(fields != null && (length = fields.length) > 0){
            mappingMetadatas = new EsFieldData[length];
            for (int i = 0; i < length; i++) {
                if(fields[i].getName().equals("serialVersionUID")){
                    continue;
                }
                mappingMetadatas[i] = getDocEsMappingMetadata(fields[i]);
            }
        }
        return mappingMetadatas;
    }
}
